#pragma once
#include "Command.hpp"
#include <functional>
#include <fstream>
#include <string>
#include "Log.hpp"
#include "InetArr.hpp"
#include "User.hpp"
#include "PthreadPool.hpp"
#include <functional>
using task_t = std::function<void(void)>;

using namespace PthreadPoolModule;

class UdpServer
{
public:
    UdpServer(uint16_t port = gdefaultport) : _inetAddr(port),
                                              _isrunning(false)
    {
    }

    void InitServer()
    {
        // 1. 创建socket
        _sockfd = socket(AF_INET, SOCK_DGRAM, 0);
        if (_sockfd < 0)
        {
            perror("socket error");
            return;
        }

        // 加载进入内核
        int n = bind(_sockfd, _inetAddr.NetAddr(), _inetAddr.NetAddrLen());
        if (n == -1)
        {
            perror("bind error");
            return;
        }
        std::cout << "bind success port:" << _inetAddr.Port() << std::endl;
    }

    void Start()
    {
        if (_isrunning)
            return;

        _isrunning = true;
        std::cout << "Begining receive" << std::endl;
        // 服务器死循环接受数据
        while (true)
        {
            struct sockaddr_in client_addr;
            socklen_t addr_len = sizeof(client_addr);
            char buffer[1024];
            // 阻塞接受
            ssize_t n = recvfrom(_sockfd, buffer, sizeof(buffer) - 1, 0, CONV(&client_addr), &addr_len);
            if (n == -1)
            {
                perror("recvfrom error");
                continue;
            }
            buffer[n] = 0;

            InetAddr inet(client_addr);
            printf("from %s:%s\n", inet.Addr().c_str(), buffer);
            std::string message=buffer;

            if(message=="我走了！")
            {
                _userMessage.DeleteUser(inet);
                message=inet.Addr()+message;
            }
            else
            {
                _userMessage.AddUser(inet);
            }

            this->_userMessage.Route(_sockfd, message);
            // // 回显
            // PthreadPool<task_t>::getInstance()->Enque([this,buffer](){
            //     LOG(LogLevel::DEBUG) <<"开始转发";
            //     this->_userMessage.Route(_sockfd, buffer);
            // });

        }
    }

    ~UdpServer()
    {
        if (_isrunning)
            ::close(_sockfd);
    }

private:
    int _sockfd;
    InetAddr _inetAddr;
    bool _isrunning; // 服务器运行状态
    UserManage _userMessage;
};
